package com.usian.admin.service.impl;

import com.fasterxml.jackson.core.type.TypeReference;
import com.usian.admin.entity.AdChannel;
import com.usian.admin.service.IAdChannelService;
import com.usian.admin.service.IAdSensitiveService;
import com.usian.admin.service.WemediaNewsAutoService;
import com.usian.article.client.ArticleClient;
import com.usian.common.aliyun.GreenImageScan;
import com.usian.common.aliyun.GreenTextScan;
import com.usian.common.dtos.PageResult;
import com.usian.common.dtos.ResponseResult;
import com.usian.common.enums.AppHttpCodeEnum;
import com.usian.common.exception.LeadException;
import com.usian.common.util.JsonUtils;
import com.usian.common.util.SensitiveWordUtil;
import com.usian.model.admin.dtos.NewsAuthDto;
import com.usian.model.media.dtos.WmNewsDto;
import com.usian.model.media.dtos.WmNewsResultDTO;
import com.usian.wemedia.client.WemediaFeign;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;

/**
 * @author Fay
 * @date 2022/7/12&11:19
 */
@Slf4j
@Service
public class WemediaNewsAutoServiceImpl implements WemediaNewsAutoService {
    /**
     * 审核自媒体文章
     * @param wmNewId
     */
    @Autowired
    private WemediaFeign wemediaFeign;
    @Autowired
    private IAdSensitiveService adSensitiveService;
    @Autowired
    private GreenImageScan greenImageScan;
    @Autowired
    private GreenTextScan greenTextScan;
    @Autowired
    private IAdChannelService adChannelService;
    @Autowired
    private ArticleClient articleClient;
    @Override
    @GlobalTransactional //开启全局事务
    public void auditWemediaNews(Integer wmNewId) {
//        远程调用-wemedia服务，根据wmNewsId查询自媒体文章信息
        ResponseResult<WmNewsResultDTO> result = wemediaFeign.findById(wmNewId);
        WmNewsResultDTO wmNewsResultDTO = result.getData();
        if (wmNewsResultDTO==null){
            throw new LeadException(AppHttpCodeEnum.DATA_NOT_EXIST,"数据不存在");
        }
        Integer status = wmNewsResultDTO.getStatus();
//        判断自媒体文章状态，进行操作
//           如果是 1 -待审核
        if (status==1){
            //获取所有的文章内容和图片
            Map<String,Object> map = getTextAndImage(wmNewsResultDTO.getTitle(),wmNewsResultDTO.getContent(),wmNewsResultDTO.getImages());
//               检查敏感词
            //查询所有敏感词
            List<String> allSensitive = adSensitiveService.findAllSensitive();
            //对文字进行校验
            Boolean b = handleSensitive(String.valueOf(map.get("text")),allSensitive,wmNewId);
            //敏感词
            if (!b){
                return;
            }
//               调用阿里云的接口审核文字

            Boolean b1= handleTextScan(String.valueOf(map.get("text")),wmNewId);
            if (!b1){
                return;
            }
//               调用阿里云的接口审核图片
            Boolean b2 = handleImageScan((List<String>)map.get("image"),wmNewId);
            if (!b2){
                return;
            }
//               如果上面的检查都通过
            //3.4 审核通过，远程调用自媒体微服务修改自媒体文章状态
            updateWmNews(wmNewId,"通过",WmNewsResultDTO.Status.SUCCESS.getCode());

//               远程调用-修改自媒体文章状态为9-审核通过
//               远程调用-保存自媒体文章信息到文章库
        }
        //判断发布时间是否存在 发布时间大于当前时间 return
        if (wmNewsResultDTO.getPublishTime()!=null && wmNewsResultDTO.getPublishTime().getTime()>new Date().getTime()){
            return;
        }
        //如果是4或者8掉修改 修改
        updateWmNews(wmNewId,"通过",WmNewsResultDTO.Status.PUBLISHED.getCode());

//           如果是 4 -人工审核通过，远程调用 -保存自媒体文章信息到文章库
//           如果是 8 -审核通过待发布， 远程调用 -保存自媒体文章信息到文章库
        //设置自媒体文章channl
        AdChannel adChannel = adChannelService.getById(wmNewsResultDTO.getChannelId());
        //封装名称
        String name = adChannel.getName();
        wmNewsResultDTO.setChannelName(name);
        //最后添加
        articleClient.saveArticle(wmNewsResultDTO);
    }

    /**
     * 审核待发布文章
     */
    @Override
    public void auditWmNewsTask() {
        //        获取需要被审核的文章id
        List<Integer> ids = wemediaFeign.findPub();
        if(CollectionUtils.isEmpty(ids)){
            log.info("没有需要审核的文章");
            return ;
        }
        for (Integer id : ids) {
            log.info("需要审核的文章id：{}",id);
            this.auditWemediaNews(id);
        }
    }

    private Boolean handleImageScan(List<String> image, Integer wmNewId) {
        try {
            Map<String, String> map = greenImageScan.imageScan(image);
            if (CollectionUtils.isEmpty(map)){
                throw new LeadException(AppHttpCodeEnum.SERVER_ERROR,"阿里云检测图片调用失败");
            }
            String suggestion = map.get("suggestion");
            if (suggestion.equals("pass")){
                return true;
            }
            Integer status= "review".equals(suggestion)?WmNewsResultDTO.Status.ADMIN_AUTH.getCode():WmNewsResultDTO.Status.FAIL.getCode();
            //更新自媒体文章状态
            updateWmNews(wmNewId,map.get("label"),status);
            return false;
        } catch (Exception e) {
            e.printStackTrace();
            throw new LeadException(AppHttpCodeEnum.SERVER_ERROR,"阿里云检测图片调用失败");
        }
    }

    /**
     * 用阿里云的接口对文字进行审核
     * @param text
     * @param wmNewId
     * @return
     */
    private Boolean handleTextScan(String text, Integer wmNewId) {
        try {
            Map<String, String> map = greenTextScan.greenTextScan(text);
            if (CollectionUtils.isEmpty(map)){
                throw new LeadException(AppHttpCodeEnum.SERVER_ERROR,"调用阿里云出现错误");
            }
            //不为空获取suggestion
            String suggestion = map.get("suggestion");
            //如果=pass
            if (suggestion.equals("pass")){
                //审核通过
                return true;
            }
            //如过等于review需要人工审核 否则就是有违规内容
            Integer status= "review".equals(suggestion)?WmNewsResultDTO.Status.ADMIN_AUTH.getCode():WmNewsResultDTO.Status.FAIL.getCode();
            //将文字状态更新
            updateWmNews(wmNewId,map.get("review"),status);
            return false;
        } catch (Exception e) {
            e.printStackTrace();
            throw new LeadException(AppHttpCodeEnum.SERVER_ERROR,"调用阿里云文本反垃圾异常");
        }
    }

    /**
     * 对文字进行校验
     * @param text 所有文字
     * @param allSensitive 敏感词
     * @param wmNewId 自媒体文章id
     * @return
     */
    private Boolean handleSensitive(String text, List<String> allSensitive, Integer wmNewId) {
        //text中是否包含有自定义敏感词
        Map<String, Integer> map = SensitiveWordUtil.matchWords(allSensitive, text);
        if (!CollectionUtils.isEmpty(map)){
            //不等于空就是有敏感词
            //通过feign去远程调用审核失败原因和状态 用枚举来表示2
            updateWmNews(wmNewId,"存在自定义敏感词",WmNewsResultDTO.Status.FAIL.getCode());
            return false;
        }
        return true;
    }

    /**
     * 去修改文章状态
     * @param wmNewId
     * @param reason
     * @param code
     */
    @Override
    public void updateWmNews(Integer wmNewId, String reason, int code) {
        WmNewsDto wmNewsDto = new WmNewsDto();
        wmNewsDto.setId(wmNewId);
        wmNewsDto.setReason(reason);
        wmNewsDto.setStatus(code);
        wemediaFeign.updateWmNews(wmNewsDto);
    }

    @Override
    public PageResult<WmNewsResultDTO> findWmNewsByPage(NewsAuthDto newsAuthDto) {
        return wemediaFeign.findWmNewsByPage(newsAuthDto);
    }

    @Override
    public ResponseResult<WmNewsResultDTO> findOneWmNews(Integer wmNewsId) {
        return wemediaFeign.findById(wmNewsId);

    }

    /**
     * 将用户的文字和图片拼接
     * @param title
     * @param content
     * @param images
     * @return
     */
    private Map<String, Object> getTextAndImage(String title, String content, String images) {
        //对title和content做判断
        if (StringUtils.isEmpty(title) || StringUtils.isEmpty(content)){
            throw new LeadException(AppHttpCodeEnum.DATA_NOT_EXIST,"文章内容不存在");
        }
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(title);
        //解析文章内容，获取文章文本和图片
        /*[{"type":"image","value":"https://usian-leadnews.oss-cn-beijing.aliyuncs.com/5dd498f9-8f6c-407a-b160-8d3d89cd83f6.jpg"},{"type":"text","value":"可爱的小猫咪一只"}*/
        //对content进行解析
        List<Map<String, String>> mapList = JsonUtils.nativeRead(content, new TypeReference<List<Map<String, String>>>() {});
        ArrayList<String> list = new ArrayList<>();
        for (Map<String, String> map : mapList) {
            if ("text".equals(map.get("type"))){
                stringBuilder.append(map.get("value"));
            }
            if ("image".equals(map.get("type"))){
                String imageUrl = map.get("value");
                list.add(imageUrl);
            }
        }
        //处理封面图片地址
        if (!StringUtils.isEmpty(images)){
            String[] split = images.split(",");
            List<String> imageList = Arrays.asList(split);
            list.addAll(imageList);
        }
        HashMap<String,Object> hashMap = new HashMap<>();
        hashMap.put("text",stringBuilder);
        hashMap.put("image",list);
        return hashMap;
    }
}
